//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#include <buola/buola.h>

#include <buola/app/cfinishfunction.h>
#include <buola/tty/output.h>
#include <buola/io.h>

namespace buola {

CFinishFunction::CFinishFunction(tFunction pFunc,const std::wstring &pName,int pPriority)
{
    mName=pName;
    mFunc=pFunc;
    mDone=false;
    mPriority=pPriority;

    GetSet(this);
}

bool CFinishFunction::Run()
{
    mDone=true;

    msg_debug<5>() << "Finishing " << mName << "...";

    bool lRet=mFunc();

    if(!lRet)
        msg_debug<5>() << tty::color(tty::COLOR_RED,"Failed!\n");
    else
        msg_debug<5>() << tty::color(tty::COLOR_GREEN,"OK\n");

    return lRet;
}

bool CFinishFunction::RunAll()
{
    CFinishFunction *lFunc;

    while((lFunc=GetSet()))
    {
        if(!lFunc->Run())
        {
            fatal_error("Error in finalization functions\n");
        }
    }

    return true;
}

CFinishFunction *CFinishFunction::GetSet(CFinishFunction *pItem)
{
    static std::vector<CFinishFunction*> lAll;
    static bool lDone=false;

    if(pItem)
    {
        lAll.push_back(pItem);
        if(lDone)
            pItem->Run();
        else
        {
            sort(lAll.begin(),lAll.end(),GenericCompare);
        }
    }
    else
    {
        for(int i=0;i<lAll.size();i++)
        {
            if(!lAll[i]->mDone) return lAll[i];
        }
        lDone=true;
    }

    return nullptr;
}

bool CFinishFunction::GenericCompare(CFinishFunction *p1,CFinishFunction *p2)
{
    return p1->mPriority<p2->mPriority;
}

/*namespace buola*/ }
